package com.alibaba.citrus.cr.platform.enhance.facade.service.scitem;

import cn.hutool.core.util.NumberUtil;
import com.alibaba.citrus.cr.common.annotation.FacadeInvoker;
import com.alibaba.citrus.cr.common.exception.FacadeException;
import com.alibaba.citrus.cr.common.util.TimeUtil;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcorder.model.dto.BaselineQueryScItemByPageFromDbRequest;
import com.epoch.app.bcorder.service.BaseDataService;
import com.epoch.app.crplatformenhance.model.dto.ScItemMultipleImportListRequest;
import com.epoch.app.crplatformenhance.model.dto.ScItemMultipleImportRequest;
import com.epoch.app.crplatformenhance.model.dto.ScItemMultipleLoadListRequest;
import com.epoch.app.crplatformenhance.model.dto.ScItemSDO;
import com.epoch.app.crplatformenhance.scitemmultiple.dto.CreateResponse;
import com.epoch.app.crplatformenhance.scitemmultiple.dto.LoadRequest;
import com.epoch.app.crplatformenhance.scitemmultiple.model.ScItemMultiple;
import com.epoch.app.crplatformenhance.scitemmultiple.service.ScItemMultipleService;
import com.epoch.app.crplatformenhance.scitemmultiplewrite.dto.CreateRequest;
import com.epoch.app.crplatformenhance.scitemmultiplewrite.dto.DeleteRequest;
import com.epoch.app.crplatformenhance.scitemmultiplewrite.dto.UpdateRequest;
import com.epoch.app.crplatformenhance.scitemmultiplewrite.service.ScItemMultipleWriteService;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @description: 货品倍数写服务
 * @author: yuhw
 * @date: 2023年02月23日 11:27
 **/
@Primary
@Component
public class ScItemMultipleWriteServiceImpl implements ScItemMultipleWriteService {
    private  Log log = Log.getLogger(ScItemMultipleWriteServiceImpl.class);

    @Resource
    private ScItemMultipleService scItemMultipleService;
    @Resource
    private BaseDataService baseDataService;

    private static final String DEFAULT_UNIT = "PC";

    @FacadeInvoker(value = "货品倍数新增", errorCode = "OTS-01-001-01-15-050")
    @Override
    public Result<Long> create(CreateRequest createRequest) {
        log.info("ScItemMultipleWriteServiceImpl_create_request:{}",JSON.toJSONString(createRequest));
        check(createRequest);

        ScItemMultipleLoadListRequest request = new ScItemMultipleLoadListRequest();
        request.setScItemId(createRequest.getScItemId());
        BaselineQueryScItemByPageFromDbRequest dbRequest = new BaselineQueryScItemByPageFromDbRequest();
        dbRequest.setIdList(Lists.newArrayList(createRequest.getScItemId()));
        dbRequest.setStatusList(Lists.newArrayList(1,-1));
        Object scItems = baseDataService.baselineQueryScItemByPageFromDb(dbRequest);
        log.info("ScItemMultipleWriteServiceImpl_create_getScItem_result:{}",JSON.toJSONString(scItems));
        List<ScItemSDO> scItemSDOS = convertResult2ScItemSDOList(scItems);
        if (CollectionUtils.isEmpty(scItemSDOS)){
            throw new FacadeException("OTS-01-001-01-15-054");
        }
        Map<String, String> features = scItemSDOS.get(0).getFeatures();
        if (features == null || !Objects.equals(features.get("unitName"),createRequest.getUnit())){
            throw new FacadeException("OTS-01-001-01-15-064");
        }
        Result<List<ScItemMultiple>> listResult = scItemMultipleService.loadList(request);
        if (listResult != null && CollectionUtils.isNotEmpty(listResult.getResult())){
            throw new FacadeException("OTS-01-001-01-15-055");
        }
        ScItemSDO scItemSDO = scItemSDOS.get(0);
        ScItemMultiple scItemMultiple = new ScItemMultiple();
        scItemMultiple.setScItemId(createRequest.getScItemId());
        scItemMultiple.setMultiple(Integer.parseInt(createRequest.getMultiple().trim()));
        scItemMultiple.setScItemCode(scItemSDO.getOuterId());
        scItemMultiple.setScItemName(scItemSDO.getTitle());
        scItemMultiple.setUnit(createRequest.getUnit());
        CreateResponse createResponse = scItemMultipleService.create(scItemMultiple);
        if (createResponse.getLastInsertId() == null){
            throw new FacadeException("OTS-01-001-01-15-050");
        }
        return Result.success(createResponse.getLastInsertId());
    }



    @FacadeInvoker(value = "货品倍数编辑", errorCode = "OTS-01-001-01-15-056")
    @Override
    public Result<Long> update(UpdateRequest updateRequest) {
        log.info("ScItemMultipleWriteServiceImpl_update_request:{}",JSON.toJSONString(updateRequest));
        //参数校验
        check(updateRequest);
        LoadRequest loadRequest = new LoadRequest();
        loadRequest.setId(updateRequest.getId());
        ScItemMultiple load = scItemMultipleService.load(loadRequest);
        if (load == null){
            throw new FacadeException("OTS-01-001-01-15-058");
        }
        load.setMultiple(Integer.parseInt(updateRequest.getMultiple().trim()));
        scItemMultipleService.update(load);
        return Result.success(load.getId());
    }

    @FacadeInvoker(value = "货品倍数删除",errorCode = "OTS-01-001-01-15-060")
    @Override
    public Result<Long> delete(DeleteRequest deleteRequest) {
        log.info("ScItemMultipleWriteServiceImpl_delete_request:{}",JSON.toJSONString(deleteRequest));
        if (StringUtils.isBlank(deleteRequest.getId())){
            throw new FacadeException("OTS-01-001-01-15-059");
        }
        com.epoch.app.crplatformenhance.scitemmultiple.dto.DeleteRequest request =
                new com.epoch.app.crplatformenhance.scitemmultiple.dto.DeleteRequest();
        request.setId(Long.parseLong(deleteRequest.getId()));
        scItemMultipleService.delete(request);
        return Result.success(request.getId());
    }

    @FacadeInvoker(value = "货品倍数导入", errorCode = "OTS-01-001-01-15-061")
    @Override
    public Result<List<ScItemMultipleImportRequest>> importData(ScItemMultipleImportListRequest scItemMultipleImportListRequest) {
        log.info("ScItemMultipleWriteServiceImpl_importData_request:{}",JSON.toJSONString(scItemMultipleImportListRequest));
        List<ScItemMultipleImportRequest> importRequestList = scItemMultipleImportListRequest.getImportRequestList();
        importCheck(importRequestList);
        //获取货品参数
        List<String> scItemCodes = importRequestList.stream()
                .map(ScItemMultipleImportRequest::getScItemCode)
                .filter(StringUtils::isNotBlank)
                .distinct().collect(Collectors.toList());
        List<ScItemSDO> scItems = getScItems(scItemCodes);
        Map<String, ScItemSDO> scItemSDOMap = Maps.newHashMap();
        if (CollectionUtils.isNotEmpty(scItems)){
            scItemSDOMap = scItems.stream().collect(Collectors.toMap(ScItemSDO::getOuterId, x -> x, (a, b) -> a));
        }
        List<ScItemMultipleImportRequest> checkSuccessList = importRequestList.stream()
                .filter(request -> StringUtils.isBlank(request.getErrorMessage()))
                .collect(Collectors.toList());
        for (ScItemMultipleImportRequest request : checkSuccessList) {
            if (!scItemSDOMap.containsKey(request.getScItemCode())){
                request.setErrorMessage("货品编码未查询到货品");
                continue;
            }
            ScItemSDO scItemSDO = scItemSDOMap.get(request.getScItemCode());
            if (scItemSDO == null){
                request.setErrorMessage("货品编码未查询到货品");
                continue;
            }
            String scItemId = scItemSDO.getScItemId();
            if (StringUtils.isBlank(scItemId)){
                request.setErrorMessage("货品编码未查询到货品");
                continue;
            }
            if (!Objects.equals(request.getUnit(),scItemSDO.getFeatures().get("unitName"))){
                request.setErrorMessage("货品基本单位不匹配");
                continue;
            }
            if (StringUtils.isNotBlank(request.getScItemName()) &&
                    !request.getScItemName().trim().equals(scItemSDO.getTitle())){
                request.setErrorMessage("货品名称不匹配");
                continue;
            }

            try{
                ScItemMultipleLoadListRequest loadListRequest = new ScItemMultipleLoadListRequest();
                loadListRequest.setScItemId(scItemId);
                Result<List<ScItemMultiple>> listResult = scItemMultipleService.loadList(loadListRequest);
                if (listResult != null && CollectionUtils.isNotEmpty(listResult.getResult())){
                    List<ScItemMultiple> scItemMultiples = listResult.getResult();
                    ScItemMultiple scItemMultiple = scItemMultiples.get(0);
                    scItemMultiple.setScItemId(scItemId);
                    scItemMultiple.setScItemCode(request.getScItemCode());
                    scItemMultiple.setMultiple(Integer.parseInt(request.getMultiple()));
                    scItemMultiple.setScItemName(scItemSDO.getTitle());
                    scItemMultiple.setUnit(request.getUnit());
                    scItemMultipleService.update(scItemMultiple);
                }else {
                    ScItemMultiple scItemMultiple = new ScItemMultiple();
                    scItemMultiple.setMultiple(Integer.parseInt(request.getMultiple()));
                    scItemMultiple.setScItemId(scItemId);
                    scItemMultiple.setScItemName(scItemSDO.getTitle());
                    scItemMultiple.setUnit(request.getUnit());
                    scItemMultiple.setScItemCode(request.getScItemCode());
                    scItemMultipleService.create(scItemMultiple);
                }
            }catch (Throwable e){
                log.error("ScItemMultipleWriteServiceImpl_import_error",e);
                request.setErrorMessage("货品导入时创建/更新失败");
            }
        }
        log.info("ScItemMultipleWriteServiceImpl_importData_result:{}",JSON.toJSONString(importRequestList));
        return Result.success(importRequestList);
    }

    private void importCheck(List<ScItemMultipleImportRequest> requests){
        if (CollectionUtils.isEmpty(requests)){
            return;
        }
        for (ScItemMultipleImportRequest request : requests) {
            if (StringUtils.isBlank(request.getScItemCode())){
                request.setErrorMessage("货品编码不能为空");
                continue;
            }
            if (StringUtils.isBlank(request.getMultiple())){
                request.setErrorMessage("货品倍数不能为空");
                continue;
            }
            if (!NumberUtil.isInteger(request.getMultiple().trim()) ||
                    Integer.parseInt(request.getMultiple().trim()) <=0
                || Integer.parseInt(request.getMultiple().trim()) > Math.pow(10,9)){
                request.setErrorMessage("货品倍数需要是小于1000000000的正整数");
                continue;
            }
            if (StringUtils.isBlank(request.getUnit())){
                request.setErrorMessage("基本单位不能为空");
                continue;
            }
            trim(request);
        }
        //货品相同的校验
        requests.stream().collect(Collectors.groupingBy(request -> Optional.ofNullable(request.getScItemCode()))).values().forEach(r -> {
            if (CollectionUtils.isNotEmpty(r) && r.size() > 1){
                r.forEach(request -> {
                    request.setErrorMessage("货品编码重复");
                });
            }
        });
    }

    private void trim(ScItemMultipleImportRequest request){
        if (request == null){
            return;
        }
        if (StringUtils.isNotBlank(request.getScItemCode())){
            request.setScItemCode(request.getScItemCode().trim());
        }
        if (StringUtils.isNotBlank(request.getMultiple())){
            request.setMultiple(request.getMultiple().trim());
        }
        if (StringUtils.isNotBlank(request.getUnit())){
            request.setUnit(request.getUnit().trim());
        }
    }

    private void check(UpdateRequest updateRequest){
        if (updateRequest.getId() == null){
            throw new FacadeException("OTS-01-001-01-15-057");
        }
        if (StringUtils.isBlank(updateRequest.getMultiple()) ||
                !NumberUtil.isInteger(updateRequest.getMultiple().trim()) ||
                Integer.parseInt(updateRequest.getMultiple().trim()) <=0 ||
                Integer.parseInt(updateRequest.getMultiple().trim()) > Math.pow(10,9)
            ){
            throw new FacadeException("OTS-01-001-01-15-052");
        }

    }

    private void check(CreateRequest createRequest){
        if (StringUtils.isBlank(createRequest.getScItemId())){
            throw new FacadeException("OTS-01-001-01-15-051");
        }
        if (StringUtils.isBlank(createRequest.getMultiple()) ||
                !NumberUtil.isInteger(createRequest.getMultiple().trim()) ||
                Integer.parseInt(createRequest.getMultiple().trim()) <=0){
            throw new FacadeException("OTS-01-001-01-15-052");
        }
        if (StringUtils.isBlank(createRequest.getUnit())){
            throw new FacadeException("OTS-01-001-01-15-063");
        }
//        if (!DEFAULT_UNIT.equals(createRequest.getUnit())){
//            throw new FacadeException("OTS-01-001-01-15-053");
//        }
    }

    private List<ScItemSDO> getScItems(List<String> scItemCodes){
        if (CollectionUtils.isEmpty(scItemCodes)){
            return null;
        }
        BaselineQueryScItemByPageFromDbRequest dbRequest = new BaselineQueryScItemByPageFromDbRequest();
        dbRequest.setOutIdList(scItemCodes);
        dbRequest.setBusinessType("11");//业态常温
        dbRequest.setType(0);//非组合货品
        dbRequest.setStatusList(Lists.newArrayList(1,-1));
        dbRequest.setLimit(3000);
        log.info("ScItemMultipleWriteServiceImpl_importData_getScItems_request:{}",JSON.toJSONString(dbRequest));
        Object scItems = baseDataService.baselineQueryScItemByPageFromDb(dbRequest);
        log.info("ScItemMultipleWriteServiceImpl_importData_getScItems_result:{}",JSON.toJSONString(scItems));
        List<ScItemSDO> scItemSDOS = convertResult2ScItemSDOList(scItems);
        return scItemSDOS;
    }

    /**
     * 中台货品转换
     * @param data
     * @return
     */
    private List<ScItemSDO> convertResult2ScItemSDOList(Object data){
        if (data == null){
            return null;
        }
        JSONObject object = JSON.parseObject(JSON.toJSONString(data));
        if (object == null){
            return null;
        }
        JSONObject result = object.getJSONObject("result");
        if (result == null){
            return null;
        }
        JSONObject resultJSONObject = result.getJSONObject("result");
        if (resultJSONObject == null){
            return null;
        }
        JSONArray content = resultJSONObject.getJSONArray("content");
        if (content == null || content.size() ==0){
            return null;
        }
        List<ScItemSDO> scItemSDOS = Lists.newArrayList();
        for (int i = 0; i < content.size(); i++) {
            JSONObject jsonObject = content.getJSONObject(i);
            scItemSDOS.add(scItemConverter(jsonObject));
        }
        return scItemSDOS;
    }
    /**
     * 货品模型转换
     * **/
    private ScItemSDO scItemConverter(JSONObject obj) {
        ScItemSDO scItemSDO = new ScItemSDO();
        scItemSDO.setBarCode(obj.getString("barCode"));
        // 这里需要查询品牌
        scItemSDO.setBrandId(obj.getString("brandId"));
        scItemSDO.setScItemId(obj.getString("scItemId"));
        scItemSDO.setLeafCategoryId(obj.getString("leafCategoryId"));
        //  实际蒙牛货品的很多字段都在features中
        scItemSDO.setFeatures((Map) obj.get("features"));
        scItemSDO.setOuterId(obj.getString("outerId"));
        scItemSDO.setTitle(obj.getString("title"));
        scItemSDO.setType(Integer.getInteger(obj.getString("type")));
        scItemSDO.setUnit(obj.getString("unit"));
        scItemSDO.setStatus(Objects.isNull(obj.getString("status")) ? -1 : Double.valueOf(obj.getString("status")).intValue());
        if (Objects.nonNull(obj.getString("gmtModified"))) {
            String gmtModifiedStr = obj.getString("gmtModified");
            Date gmtModified = TimeUtil.parseTime(gmtModifiedStr);
            scItemSDO.setGmtModified(gmtModified);
        }
        if (Objects.nonNull(obj.getString("gmtCreate"))) {
            String gmtCreateStr = obj.getString("gmtCreate");
            Date gmtCreate = TimeUtil.parseTime(gmtCreateStr);
            scItemSDO.setGmtCreate(gmtCreate);
        }
        return scItemSDO;
    }

}
